package com.sora.pipeline.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sora.pipeline.common.api.ApiResponse;
import com.sora.pipeline.domain.InspectionPlan;
import com.sora.pipeline.domain.InspectionTask;
import com.sora.pipeline.domain.Line;
import com.sora.pipeline.domain.User;
import com.sora.pipeline.domain.dto.*;
import com.sora.pipeline.service.InspectionPlanService;
import com.sora.pipeline.service.InspectionTaskService;
import com.sora.pipeline.service.LineService;
import com.sora.pipeline.service.UserService;
import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 巡检管理控制器
 * 
 * @author system
 * @since 2025-01-20
 */
@RestController
@RequestMapping("/api/inspections")
@Validated
public class InspectionController {

    @Autowired
    private InspectionPlanService inspectionPlanService;
    
    @Autowired
    private InspectionTaskService inspectionTaskService;
    
    @Autowired
    private LineService lineService;
    
    @Autowired
    private UserService userService;

    /**
     * 1. 获取巡检计划列表
     * 分页获取巡检计划列表，支持搜索和筛选，返回包含线路代码和负责人名称的详细信息
     */
    @GetMapping("/plans")
    public ApiResponse<IPage<InspectionPlanWithDetailsDTO>> getInspectionPlans(
            @RequestParam int pageNum,
            @RequestParam int pageSize,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String cycle) {
        
        LambdaQueryWrapper<InspectionPlan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(InspectionPlan::getDeleted, false);
        
        // 搜索条件
        if (StringUtils.hasText(keyword)) {
            queryWrapper.like(InspectionPlan::getName, keyword);
        }
        
        // 状态筛选
        if (StringUtils.hasText(status)) {
            queryWrapper.eq(InspectionPlan::getStatus, status);
        }
        
        // 周期筛选
        if (StringUtils.hasText(cycle)) {
            queryWrapper.eq(InspectionPlan::getCycle, cycle);
        }
        
        queryWrapper.orderByDesc(InspectionPlan::getCreatedAt);
        
        IPage<InspectionPlan> page = inspectionPlanService.page(new Page<>(pageNum, pageSize), queryWrapper);
        
        // 转换为包含详细信息的DTO
        IPage<InspectionPlanWithDetailsDTO> resultPage = page.convert(plan -> {
            InspectionPlanWithDetailsDTO dto = InspectionPlanWithDetailsDTO.fromInspectionPlan(plan);
            
            // 获取线路信息
            if (plan.getLineId() != null) {
                Line line = lineService.getById(plan.getLineId());
                if (line != null && !line.getDeleted()) {
                    dto.setLineCode(line.getLineCode());
                    dto.setLineName(line.getLineName());
                }
            }
            
            // 获取负责人信息
            if (plan.getAssigneeId() != null) {
                User assignee = userService.getById(plan.getAssigneeId());
                if (assignee != null && !assignee.getDeleted()) {
                    dto.setAssigneeName(assignee.getName());
                    dto.setAssigneeUsername(assignee.getUsername());
                }
            }
            
            return dto;
        });
        
        return ApiResponse.success(resultPage);
    }

    /**
     * 2. 获取巡检计划详情
     * 根据ID获取巡检计划详细信息
     */
    @GetMapping("/plans/{id}")
    public ApiResponse<InspectionPlan> getInspectionPlan(@PathVariable Long id) {
        InspectionPlan plan = inspectionPlanService.getById(id);
        if (plan == null || plan.getDeleted()) {
            return ApiResponse.failure(404, "巡检计划不存在");
        }
        return ApiResponse.success(plan);
    }

    /**
     * 3. 创建巡检计划
     * 创建新的巡检计划
     */
    @PostMapping("/plans")
    public ApiResponse<InspectionPlan> createInspectionPlan(@Valid @RequestBody InspectionPlanRequest request) {
        // 检查线路是否存在
        Line line = lineService.getById(request.getLineId());
        if (line == null || line.getDeleted()) {
            return ApiResponse.failure(404, "线路不存在");
        }
        
        // 检查负责人是否存在
        User assignee = userService.getById(request.getAssigneeId());
        if (assignee == null) {
            return ApiResponse.failure(404, "负责人不存在");
        }
        
        // 生成计划编号
        String code = generatePlanCode();
        
        InspectionPlan plan = new InspectionPlan();
        BeanUtils.copyProperties(request, plan);
        plan.setCode(code);
        plan.setStatus(StringUtils.hasText(request.getStatus()) ? request.getStatus() : "active");
        plan.setCreatedAt(LocalDateTime.now());
        plan.setUpdatedAt(LocalDateTime.now());
        plan.setDeleted(false);
        
        inspectionPlanService.save(plan);
        return ApiResponse.success(plan);
    }

    /**
     * 4. 更新巡检计划
     * 更新巡检计划信息
     */
    @PutMapping("/plans/{id}")
    public ApiResponse<InspectionPlan> updateInspectionPlan(@PathVariable Long id, @Valid @RequestBody InspectionPlanRequest request) {
        InspectionPlan plan = inspectionPlanService.getById(id);
        if (plan == null || plan.getDeleted()) {
            return ApiResponse.failure(404, "巡检计划不存在");
        }
        
        // 检查线路是否存在
        Line line = lineService.getById(request.getLineId());
        if (line == null || line.getDeleted()) {
            return ApiResponse.failure(404, "线路不存在");
        }
        
        // 检查负责人是否存在
        User assignee = userService.getById(request.getAssigneeId());
        if (assignee == null) {
            return ApiResponse.failure(404, "负责人不存在");
        }
        
        BeanUtils.copyProperties(request, plan);
        plan.setUpdatedAt(LocalDateTime.now());
        
        inspectionPlanService.updateById(plan);
        return ApiResponse.success(plan);
    }

    /**
     * 5. 删除巡检计划
     * 删除指定巡检计划
     */
    @DeleteMapping("/plans/{id}")
    public ApiResponse<Void> deleteInspectionPlan(@PathVariable Long id) {
        InspectionPlan plan = inspectionPlanService.getById(id);
        if (plan == null || plan.getDeleted()) {
            return ApiResponse.failure(404, "巡检计划不存在");
        }
        
        // 检查是否有关联的巡检任务
        LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(InspectionTask::getPlanId, id)
                   .eq(InspectionTask::getDeleted, false);
        long taskCount = inspectionTaskService.count(queryWrapper);
        if (taskCount > 0) {
            return ApiResponse.failure(400, "该计划下还有未完成的巡检任务，无法删除");
        }
        
        plan.setDeleted(true);
        plan.setUpdatedAt(LocalDateTime.now());
        inspectionPlanService.updateById(plan);
        
        return ApiResponse.success(null);
    }

    /**
     * 6. 获取巡检任务列表
     * 分页获取巡检任务列表，支持搜索和筛选，返回包含线路代码和负责人名称的详细信息
     */
    @GetMapping("/tasks")
    public ApiResponse<IPage<InspectionTaskWithDetailsDTO>> getInspectionTasks(
            @RequestParam int pageNum,
            @RequestParam int pageSize,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String cycle,
            @RequestParam(required = false) Long planId) {
        
        LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(InspectionTask::getDeleted, false);
        
        // 搜索条件
        if (StringUtils.hasText(keyword)) {
            queryWrapper.and(wrapper -> wrapper
                .like(InspectionTask::getCode, keyword)
                .or()
                .like(InspectionTask::getName, keyword)
            );
        }
        
        // 状态筛选
        if (StringUtils.hasText(status)) {
            queryWrapper.eq(InspectionTask::getStatus, status);
        }
        
        // 周期筛选
        if (StringUtils.hasText(cycle)) {
            queryWrapper.eq(InspectionTask::getCycle, cycle);
        }
        
        // 计划ID筛选
        if (planId != null) {
            queryWrapper.eq(InspectionTask::getPlanId, planId);
        }
        
        queryWrapper.orderByDesc(InspectionTask::getCreatedAt);
        
        IPage<InspectionTask> page = inspectionTaskService.page(new Page<>(pageNum, pageSize), queryWrapper);
        
        // 转换为包含详细信息的DTO
        IPage<InspectionTaskWithDetailsDTO> resultPage = page.convert(task -> {
            InspectionTaskWithDetailsDTO dto = InspectionTaskWithDetailsDTO.fromInspectionTask(task);
            
            // 获取线路信息
            if (task.getLineId() != null) {
                Line line = lineService.getById(task.getLineId());
                if (line != null && !line.getDeleted()) {
                    dto.setLineCode(line.getLineCode());
                    dto.setLineName(line.getLineName());
                }
            }
            
            // 获取负责人信息
            if (task.getAssigneeId() != null) {
                User assignee = userService.getById(task.getAssigneeId());
                if (assignee != null && !assignee.getDeleted()) {
                    dto.setAssigneeName(assignee.getName());
                    dto.setAssigneeUsername(assignee.getUsername());
                }
            }
            
            return dto;
        });
        
        return ApiResponse.success(resultPage);
    }

    /**
     * 7. 创建巡检任务
     * 创建新的巡检任务
     */
    @PostMapping("/tasks")
    public ApiResponse<InspectionTask> createInspectionTask(@Valid @RequestBody InspectionTaskRequest request) {
        // 检查计划是否存在（如果提供了planId）
        if (request.getPlanId() != null) {
            InspectionPlan plan = inspectionPlanService.getById(request.getPlanId());
            if (plan == null || plan.getDeleted()) {
                return ApiResponse.failure(404, "巡检计划不存在");
            }
        }
        
        // 检查线路是否存在
        Line line = lineService.getById(request.getLineId());
        if (line == null || line.getDeleted()) {
            return ApiResponse.failure(404, "线路不存在");
        }
        
        // 检查负责人是否存在（如果提供了assigneeId）
        if (request.getAssigneeId() != null) {
            User assignee = userService.getById(request.getAssigneeId());
            if (assignee == null) {
                return ApiResponse.failure(404, "负责人不存在");
            }
        }
        
        // 生成任务编号
        String code = generateTaskCode();
        
        InspectionTask task = new InspectionTask();
        BeanUtils.copyProperties(request, task);
        task.setCode(code);
        task.setStatus(StringUtils.hasText(request.getStatus()) ? request.getStatus() : "pending");
        task.setProgress(request.getProgress() != null ? request.getProgress() : 0);
        task.setCreatedAt(LocalDateTime.now());
        task.setUpdatedAt(LocalDateTime.now());
        task.setDeleted(false);
        
        inspectionTaskService.save(task);
        return ApiResponse.success(task);
    }

    /**
     * 8. 获取巡检任务详情
     * 根据ID获取巡检任务详细信息
     */
    @GetMapping("/tasks/{id}")
    public ApiResponse<InspectionTask> getInspectionTask(@PathVariable Long id) {
        InspectionTask task = inspectionTaskService.getById(id);
        if (task == null || task.getDeleted()) {
            return ApiResponse.failure(404, "巡检任务不存在");
        }
        return ApiResponse.success(task);
    }

    /**
     * 9. 更新巡检任务
     * 更新巡检任务信息
     */
    @PutMapping("/tasks/{id}")
    public ApiResponse<InspectionTask> updateInspectionTask(@PathVariable Long id, @Valid @RequestBody InspectionTaskRequest request) {
        InspectionTask task = inspectionTaskService.getById(id);
        if (task == null || task.getDeleted()) {
            return ApiResponse.failure(404, "巡检任务不存在");
        }
        
        // 检查计划是否存在（如果提供了planId）
        if (request.getPlanId() != null) {
            InspectionPlan plan = inspectionPlanService.getById(request.getPlanId());
            if (plan == null || plan.getDeleted()) {
                return ApiResponse.failure(404, "巡检计划不存在");
            }
        }
        
        // 检查线路是否存在
        Line line = lineService.getById(request.getLineId());
        if (line == null || line.getDeleted()) {
            return ApiResponse.failure(404, "线路不存在");
        }
        
        // 检查负责人是否存在（如果提供了assigneeId）
        if (request.getAssigneeId() != null) {
            User assignee = userService.getById(request.getAssigneeId());
            if (assignee == null) {
                return ApiResponse.failure(404, "负责人不存在");
            }
        }
        
        // 更新任务信息
        BeanUtils.copyProperties(request, task);
        task.setUpdatedAt(LocalDateTime.now());
        
        inspectionTaskService.updateById(task);
        return ApiResponse.success(task);
    }

    /**
     * 10. 删除巡检任务
     * 删除指定巡检任务（软删除）
     */
    @DeleteMapping("/tasks/{id}")
    public ApiResponse<Void> deleteInspectionTask(@PathVariable Long id) {
        InspectionTask task = inspectionTaskService.getById(id);
        if (task == null || task.getDeleted()) {
            return ApiResponse.failure(404, "巡检任务不存在");
        }
        
        task.setDeleted(true);
        task.setUpdatedAt(LocalDateTime.now());
        
        inspectionTaskService.updateById(task);
        return ApiResponse.success(null);
    }

    /**
     * 11. 分配巡检任务
     * 分配巡检任务给指定人员
     */
    @PostMapping("/tasks/{id}/assign")
    public ApiResponse<Void> assignTask(@PathVariable Long id, @Valid @RequestBody TaskAssignRequest request) {
        InspectionTask task = inspectionTaskService.getById(id);
        if (task == null || task.getDeleted()) {
            return ApiResponse.failure(404, "巡检任务不存在");
        }
        
        // 检查负责人是否存在
        User assignee = userService.getById(request.getAssigneeId());
        if (assignee == null) {
            return ApiResponse.failure(404, "负责人不存在");
        }
        
        task.setAssigneeId(request.getAssigneeId());
        task.setDeadline(request.getDeadline());
        task.setRemark(request.getRemark());
        task.setStatus("in_progress");
        task.setStartTime(LocalDateTime.now());
        task.setUpdatedAt(LocalDateTime.now());
        
        inspectionTaskService.updateById(task);
        return ApiResponse.success(null);
    }

    /**
     * 9. 批量分配任务
     * 批量分配多个任务
     */
    @PostMapping("/tasks/batch-assign")
    public ApiResponse<Void> batchAssignTasks(@Valid @RequestBody BatchTaskAssignRequest request) {
        List<InspectionTask> tasks = inspectionTaskService.listByIds(request.getTaskIds());
        if (tasks.isEmpty()) {
            return ApiResponse.failure(404, "没有找到要分配的任务");
        }
        
        // 检查负责人是否存在
        User assignee = userService.getById(request.getAssigneeId());
        if (assignee == null) {
            return ApiResponse.failure(404, "负责人不存在");
        }
        
        // 批量更新任务
        tasks.forEach(task -> {
            task.setAssigneeId(request.getAssigneeId());
            task.setDeadline(request.getDeadline());
            task.setRemark(request.getRemark());
            task.setStatus("in_progress");
            task.setStartTime(LocalDateTime.now());
            task.setUpdatedAt(LocalDateTime.now());
        });
        
        inspectionTaskService.updateBatchById(tasks);
        return ApiResponse.success(null);
    }

    /**
     * 10. 完成任务
     * 标记任务为已完成
     */
    @PostMapping("/tasks/{id}/complete")
    public ApiResponse<Void> completeTask(@PathVariable Long id, @Valid @RequestBody TaskCompleteRequest request) {
        InspectionTask task = inspectionTaskService.getById(id);
        if (task == null || task.getDeleted()) {
            return ApiResponse.failure(404, "巡检任务不存在");
        }
        
        if (!"in_progress".equals(task.getStatus())) {
            return ApiResponse.failure(400, "只有进行中的任务才能完成");
        }
        
        task.setStatus("completed");
        task.setCompletionTime(request.getCompletionTime());
        task.setRemark(request.getRemark());
        task.setProgress(100);
        task.setUpdatedAt(LocalDateTime.now());
        
        inspectionTaskService.updateById(task);
        return ApiResponse.success(null);
    }

    /**
     * 11. 获取任务统计信息
     * 获取任务统计数据
     */
    @GetMapping("/tasks/statistics")
    public ApiResponse<Map<String, Object>> getTaskStatistics() {
        LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(InspectionTask::getDeleted, false);
        
        long totalTasks = inspectionTaskService.count(queryWrapper);
        
        // 按状态统计
        queryWrapper.clear();
        queryWrapper.eq(InspectionTask::getDeleted, false).eq(InspectionTask::getStatus, "pending");
        long pendingCount = inspectionTaskService.count(queryWrapper);
        
        queryWrapper.clear();
        queryWrapper.eq(InspectionTask::getDeleted, false).eq(InspectionTask::getStatus, "in_progress");
        long inProgressCount = inspectionTaskService.count(queryWrapper);
        
        queryWrapper.clear();
        queryWrapper.eq(InspectionTask::getDeleted, false).eq(InspectionTask::getStatus, "completed");
        long completedCount = inspectionTaskService.count(queryWrapper);
        
        queryWrapper.clear();
        queryWrapper.eq(InspectionTask::getDeleted, false).eq(InspectionTask::getStatus, "timeout");
        long timeoutCount = inspectionTaskService.count(queryWrapper);
        
        Map<String, Object> statistics = Map.of(
            "totalTasks", totalTasks,
            "pending", pendingCount,
            "inProgress", inProgressCount,
            "completed", completedCount,
            "timeout", timeoutCount
        );
        
        return ApiResponse.success(statistics);
    }

    /**
     * 生成计划编号
     */
    private String generatePlanCode() {
        String prefix = "P-" + LocalDateTime.now().getYear() + "-";
        LambdaQueryWrapper<InspectionPlan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(InspectionPlan::getCode, prefix)
                   .orderByDesc(InspectionPlan::getCode)
                   .last("LIMIT 1");
        
        InspectionPlan lastPlan = inspectionPlanService.getOne(queryWrapper);
        if (lastPlan == null) {
            return prefix + "001";
        }
        
        String lastCode = lastPlan.getCode();
        String numberPart = lastCode.substring(prefix.length());
        int nextNumber = Integer.parseInt(numberPart) + 1;
        return prefix + String.format("%03d", nextNumber);
    }

    /**
     * 生成任务编号
     */
    private String generateTaskCode() {
        String prefix = "T-" + LocalDateTime.now().getYear() + "-";
        LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(InspectionTask::getCode, prefix)
                   .orderByDesc(InspectionTask::getCode)
                   .last("LIMIT 1");
        
        InspectionTask lastTask = inspectionTaskService.getOne(queryWrapper);
        if (lastTask == null) {
            return prefix + "001";
        }
        
        String lastCode = lastTask.getCode();
        String numberPart = lastCode.substring(prefix.length());
        int nextNumber = Integer.parseInt(numberPart) + 1;
        return prefix + String.format("%03d", nextNumber);
    }
}
